﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Linq;

namespace Recipes.BasicStoredProc
{
    /// <summary>
    /// This scenario reads from stored procedures
    /// </summary>
    [TestCategory("BasicStoredProc")]
    public abstract class BasicStoredProcTests<TEmployeeClassification, TEmployeeClassificationWithCount>
       where TEmployeeClassification : class, IEmployeeClassification, new()
       where TEmployeeClassificationWithCount : class, IEmployeeClassificationWithCount
    {
        [TestMethod]
        public void CountEmployeesByClassification()
        {
            var repository = GetScenario();

            var newRecord = new TEmployeeClassification
            {
                EmployeeClassificationName = $"Test {DateTime.Now.Ticks}",
                IsEmployee = true,
                IsExempt = false
            };

            var newKey = repository.CreateEmployeeClassification(newRecord);
            Assert.IsTrue(newKey >= 1000, "keys under 1000 were not generated by the database");

            var actuals = repository.CountEmployeesByClassification();

            Assert.IsTrue(actuals.All(x => x.EmployeeCount >= 0), "Employee Count shouldn't be less than zero");
            Assert.IsTrue(actuals.Any(x => x.EmployeeCount > 0), "At least one employee Count should be greater than zero");

            var echo = actuals.SingleOrDefault(x => x.EmployeeClassificationKey == newKey);
            Assert.IsNotNull(echo, "Newly created row wasn't found");
            Assert.AreEqual(newKey, echo!.EmployeeClassificationKey);
            Assert.AreEqual(newRecord.EmployeeClassificationName, echo.EmployeeClassificationName);
        }

        [TestMethod]
        public void CreateEmployeeClassification()
        {
            var repository = GetScenario();

            var newRecord = new TEmployeeClassification
            {
                EmployeeClassificationName = $"Test {DateTime.Now.Ticks}",
                IsEmployee = true,
                IsExempt = false
            };

            var newKey = repository.CreateEmployeeClassification(newRecord);
            Assert.IsTrue(newKey >= 1000, "keys under 1000 were not generated by the database");

            var echo = repository.GetEmployeeClassifications(newKey);
            Assert.IsNotNull(echo);
            Assert.AreEqual(newKey, echo!.EmployeeClassificationKey);
            Assert.AreEqual(newRecord.EmployeeClassificationName, echo.EmployeeClassificationName);
            Assert.AreEqual(newRecord.IsEmployee, echo.IsEmployee);
            Assert.AreEqual(newRecord.IsExempt, echo.IsExempt);
        }

        [TestMethod]
        public void GetEmployeeClassifications()
        {
            var repository = GetScenario();

            var newRecord = new TEmployeeClassification
            {
                EmployeeClassificationName = $"Test {DateTime.Now.Ticks}",
                IsEmployee = true,
                IsExempt = false
            };

            var newKey = repository.CreateEmployeeClassification(newRecord);
            Assert.IsTrue(newKey >= 1000, "keys under 1000 were not generated by the database");

            var actuals = repository.GetEmployeeClassifications();

            Assert.IsTrue(actuals.Count >= 7, "At least 7 records were expected.");

            var echo = actuals.SingleOrDefault(x => x.EmployeeClassificationKey == newKey);
            Assert.IsNotNull(echo, "Newly created row wasn't found");
            Assert.AreEqual(newKey, echo!.EmployeeClassificationKey);
            Assert.AreEqual(newRecord.EmployeeClassificationName, echo.EmployeeClassificationName);
            Assert.AreEqual(newRecord.IsEmployee, echo.IsEmployee);
            Assert.AreEqual(newRecord.IsExempt, echo.IsExempt);
        }

        [TestMethod]
        public void GetEmployeeClassifications_Int()
        {
            var repository = GetScenario();

            var newRecord = new TEmployeeClassification
            {
                EmployeeClassificationName = $"Test {DateTime.Now.Ticks}",
                IsEmployee = true,
                IsExempt = false
            };

            var newKey = repository.CreateEmployeeClassification(newRecord);
            Assert.IsTrue(newKey >= 1000, "keys under 1000 were not generated by the database");

            var echo = repository.GetEmployeeClassifications(newKey);
            Assert.IsNotNull(echo, "Newly created row wasn't found");
            Assert.AreEqual(newKey, echo!.EmployeeClassificationKey, "The wrong row was returned");
            Assert.AreEqual(newRecord.EmployeeClassificationName, echo.EmployeeClassificationName);
            Assert.AreEqual(newRecord.IsEmployee, echo.IsEmployee);
            Assert.AreEqual(newRecord.IsExempt, echo.IsExempt);
        }

        protected abstract IBasicStoredProcScenario<TEmployeeClassification, TEmployeeClassificationWithCount> GetScenario();
    }
}
